# 03. ECMAScript 6
Assembled by GimunLee
# ๊ฐ์
Angular๋ TypeScript๋ฅผ ๋์ ํ์ฌ ๋ค์ํ ๋๊ตฌ์ ์ง์์ ์ ๊ณต๋ฐ์ ์ ์๊ฒ ๋์๋ค. TypeScriptsms ES5์ ์์ฐ์งํฉ(Superset)์ด๋ฏ๋ก ES5์ ๋ฌธ๋ฒ์ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์์ผ๋ฉฐ, Babel๊ณผ ๊ฐ์ ๋ณ๋์ ํธ๋์คํ์ผ๋ฌ๋ฅผ ์ฌ์ฉํ์ง ์์๋ ๊ธฐ์กด์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง(๋ธ๋ผ์ฐ์ ๋๋ Node.js)์์ ES6์ ์๋ก์ด ๊ธฐ๋ฅ์ ์คํํ ์ ์๋ค.
# 1) let, const์ ๋ธ๋ก ๋ ๋ฒจ ์ค์ฝํ
# ๊ฐ์
ES5์์ ๋ณ์๋ฅผ ์ ์ธํ ์ ์๋ ์ ์ผํ ๋ฐฉ๋ฒ์ var ํค์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด์๋ค. var ํค์๋๋ก ์ ์ธ๋ ๋ณ์๋ ์๋์ ๊ฐ์ ํน์ง์ด ์๋ค.
ํจ์ ๋ ๋ฒจ ์ค์ฝํ: ์ ์ญ ๋ณ์์ ๋จ๋ฐ. for ๋ฃจํ์ ์ด๊ธฐํ ์์์ ์ฌ์ฉํ ๋ณ์๋ฅผ for ๋ฃจํ ์ธ๋ถ ๋๋ ์ ์ญ์์ ์ฐธ์กฐ ๊ฐ๋ฅ
var ํค์๋ ์๋ต ํ์ฉ: ์๋ํ์ง ์์ ๋ณ์์ ์ ์ญํ
์ค๋ณต ์ ์ธ ํ์ฉ: ์๋ํ์ง ์์ ๋ณ์ซ๊ฐ ๋ณ๊ฒฝ
**๋ณ์ ํธ์ด์คํ : ** ๋ณ์๋ฅผ ์ ์ธํ๊ธฐ ์ ์ ์ฐธ์กฐ ๊ฐ๋ฅ
๋๋ถ๋ถ ๋ฌธ์ ๋ ์ ์ญ ๋ณ์๋ก ์ธํด ๋ฐ์ํ๋ค. ๋ณ์์ ์ ํจ ๋ฒ์๋ ์ข์์๋ก ์ข๋ค.
# let
# ๋ธ๋ก ๋ ๋ฒจ ์ค์ฝํ
๋๋ถ๋ถ์ C-family ์ธ์ด๋ ๋ธ๋ก ๋ ๋ฒจ ์ค์ฝํ๋ฅผ ์ง์ํ์ง๋ง, ์๋ฐ์คํฌ๋ฆฝํธ๋ ํจ์ ๋ ๋ฒจ ์ค์ฝํ๋ฅผ ๊ฐ๋๋ค.
- ํจ์ ๋ ๋ฒจ ์ค์ฝํ(Function-level scope): ํจ์ ๋ด์์ ์ ์ธ๋ ๋ณ์๋ ํจ์ ๋ด์์๋ง ์ ํจํ๋ฉฐ ํจ์ ์ธ๋ถ์์๋ ์ฐธ์กฐํ ์ ์๋ค. ์ฆ ํจ์ ๋ด๋ถ์์ ์ ์ธํ ๋ณ์๋ ์ง์ญ ๋ณ์์ด๋ฉฐ ํจ์ ์ธ๋ถ์์ ์ ์ธํ ๋ณ์๋ ๋ชจ๋ ์ ์ญ ๋ณ์์ด๋ค.
- **๋ธ๋ก ๋ ๋ฒจ ์ค์ฝํ(Block-level scope): ** ์ฝ๋ ๋ธ๋ก ๋ด์์ ์ ์ธ๋ ๋ณ์๋ ์ฝ๋ ๋ธ๋ก ๋ด์์๋ง ์ ํจํ๋ฉฐ ์ฝ๋ ๋ธ๋ก ์ธ๋ถ์์๋ ์ฐธ์กฐํ ์ ์๋ค.
var ํค์๋ ์ฌ์ฉ
console.log(foo); // undefined
var foo = 123; // ์ ์ญ ๋ณ์
console.log(foo); // 123
{
var foo = 456; // ์ค๋ณต ์ ์ธ ํ์ฉ
}
console.log(foo); // 456
let ํค์๋(๋ธ๋ก ๋ ๋ฒจ ์ค์ฝํ) ์ฌ์ฉ
let foo = 123;
{
let foo = 456;
let bar = 456;
}
console.log(foo); // 123
console.log(bar); // ReferenceError: bar is not defined
# ์ค๋ณต ์ ์ธ ๊ธ์ง
var ํค์๋๋ก๋ ์ด๋ฆ์ด ๊ฐ์ ๋ณ์๋ฅผ ์ค๋ณตํด์ ์ ์ธํ ์ ์์์ง๋ง, let ํค์๋๋ก๋ ์ด๋ฆ์ด ๊ฐ์ ๋ณ์๋ฅผ ์ค๋ณตํด์ ์ ์ธํ๋ฉด ๋ฌธ๋ฒ ์๋ฌ(SyntaxError)๊ฐ ๋ฐ์ํ๋ค.
var foo = 123;
var foo = 456; // ์ค๋ณต ์ ์ธ ํ์ฉ
let bar = 123;
let bar = 456; // Uncaught SyntaxError: Identifier 'bar' has already been declared
# ํธ์ด์คํ (Hoisting)
์๋ฐ์คํฌ๋ฆฝํธ๋ ES6์์ ๋์ ๋ let, const๋ฅผ ํฌํจํ์ฌ ๋ชจ๋ ์ ์ธ(var, let, const, function, function *, class)์ ํธ์ด์คํ ํ๋ค. ํธ์ด์คํ ์ด๋, var ์ ์ธ๋ฌธ์ด๋ function ์ ์ธ๋ฌธ ๋ฑ์ ํด๋น ์ค์ฝํ์ ์ ๋๋ก ์ฎ๊ธด ๊ฒ์ฒ๋ผ ๋์ํ๋ ํน์ฑ์ ๋งํ๋ค.
ํ์ง๋ง let ํค์๋๋ก ์ ์ธ๋ ๋ณ์๋ ์ ์ธ๋ฌธ ์ด์ ์ ์ฐธ์กฐํ๋ฉด ์ฐธ์กฐ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. ์ด๋ let ํค์๋๋ก ์ ์ธ๋ ๋ณ์๋ ์ค์ฝํ์ ์์์์ ๋ณ์์ ์ ์ธ๊น์ง ์ผ์์ ์ฌ๊ฐ์ง๋(TDZ, Temporal Dead Zone) ์ ๋น ์ง๊ธฐ ๋๋ฌธ์ด๋ค.
console.log(foo); // undefined
var foo;
console.log(bar); // Error: Uncaught ReferenceError: bar is not defined
let bar;
๋ณ์๋ 3๋จ๊ณ์ ๊ฑธ์ณ ์์ฑ๋๋ค.
- ์ ์ธ ๋จ๊ณ(Declaration phase): ๋ณ์๋ฅผ ์คํ ์ปจํ ์คํธ์ ๋ณ์ ๊ฐ์ฒด(Variable Object)์ ๋ฑ๋กํ๋ค. ์ด ๋ณ์ ๊ฐ์ฒด๋ ์ค์ฝํ๊ฐ ์ฐธ์กฐํ๋ ๋์์ด ๋๋ค.
- ์ด๊ธฐํ ๋จ๊ณ(Initialization phase): ๋ณ์ ๊ฐ์ฒด์ ๋ฑ๋ก๋ ๋ณ์๋ฅผ ์ํ ๊ณต๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ํ๋ณดํ๋ค. ์ด ๋จ๊ณ์์ ๋ณ์๋ undefined๋ก ์ด๊ธฐํ ๋๋ค.
- ํ ๋น ๋จ๊ณ(Assignment phase): undefined๋ก ์ด๊ธฐํ๋ ๋ณ์์ ์ค์ ๊ฐ์ ํ ๋นํ๋ค.
var ํค์๋๋ก ์ ์ธ๋ ๋ณ์๋ ์ ์ธ ๋จ๊ณ์ ์ด๊ธฐํ ๋จ๊ณ๊ฐ ํ๋ฒ์ ์ด๋ฃจ์ด์ง๋ค. ํ์ง๋ง let ํค์๋๋ก ์ ์ธ๋ ๋ณ์๋ ์ ์ธ ๋จ๊ณ์ ์ด๊ธฐํ ๋จ๊ณ๊ฐ ๋ถ๋ฆฌ๋์ด ์งํ๋๋ค. ์ฆ, ์ค์ฝํ์ ๋ณ์๋ฅผ ๋ฑ๋ก(์ ์ธ ๋จ๊ณ)ํ์ง๋ง ์ด๊ธฐํ ๋จ๊ณ๋ ๋ณ์ ์ ์ธ๋ฌธ์ ๋๋ฌํ์ ๋ ์ด๋ฃจ์ด์ง๋ค. ์ค์ฝํ์ ์์ ์ง์ ๋ถํฐ ์ด๊ธฐํ ์์ ์ง์ ๊น์ง์ ๊ตฌ๊ฐ์ '์ผ์์ ์ฌ๊ฐ์ง๋(Temporal Dead Zone)' ๋ผ๊ณ ๋ถ๋ฅธ๋ค.
๊ฒฐ๊ตญ ES6์์๋ ํธ์ด์คํ์ด ๋ฐ์ํ์ง ์๋ ๊ฒ๊ณผ ์ฐจ์ด๊ฐ ์์ด ๋ณด์ธ๋ค. ํ์ง๋ง ๊ทธ๋ ์ง ์๋ค.
let foo = 1; // ์ ์ญ ๋ณ์
{
// let foo; // ํธ์ด์คํ
console.log(foo); // ReferenceError: foo is not defined
let foo = 2;
}
์์ ์์ ๋ ํธ์ด์คํ ์ด ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ์ฐธ์กฐ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
# ์ ์ญ ๊ฐ์ฒด์ let
์ ์ญ ๊ฐ์ฒด(Global Object)๋ ๋ชจ๋ ๊ฐ์ฒด์ ์ ์ผํ ์ต์์ ๊ฐ์ฒด๋ฅผ ์๋ฏธํ๋ฉฐ ์ผ๋ฐ์ ์ผ๋ก ๋ธ๋ผ์ฐ์ ์ฌ์ด๋์์๋ window ๊ฐ์ฒด, ์๋ฒ ์ฌ์ด๋(Node.js)์์๋ global ๊ฐ์ฒด๋ฅผ ์๋ฏธํ๋ค. var ํค์๋๋ก ์ ์ธ๋ ๋ณ์๋ฅผ ์ ์ญ ๋ณ์๋ก ์ฌ์ฉํ๋ฉด ์ ์ญ ๊ฐ์ฒด์ ํ๋กํผํฐ๊ฐ ๋๋ค.
var foo = 123; // ์ ์ญ ๋ณ์
console.log(window.foo); // 123
let ํค์๋๋ก ์ ์ธ๋ ๋ณ์๋ฅผ ์ ์ญ ๋ณ์๋ก ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, let ์ ์ญ ๋ณ์๋ ์ ์ญ ๊ฐ์ฒด์ ํ๋กํผํฐ๊ฐ ์๋๋ค. ์ฆ, window.foo์ ๊ฐ์ด ์ ๊ทผํ ์ ์๋ค. let ์ ์ญ ๋ณ์๋ ๋ณด์ด์ง ์๋ ๊ฐ๋ ์ ์ธ ๋ธ๋ก ๋ด์ ์กด์ฌํ๊ฒ ๋๋ค.
let foo = 123; // ์ ์ญ ๋ณ์
console.log(window.foo); // undefined